/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.ndj.conexao;

import br.com.ndj.exceptions.FabricaConexaoPoolVazioException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author 
 */
public class FabricaConexao {

    
    private static FabricaConexao instance;
    
    /*** MYSQL ***/
    private final String url = "jdbc:mysql://127.0.0.1:3306/neurodata";
    private final String user = "root";
    private final String pass = "F3bR3t!foide";
    private final String driver = "com.mysql.jdbc.Driver";

    List<Connection> connectionPool;

    public static FabricaConexao getInstance() {
        if (instance == null) {
            instance = new FabricaConexao();
        }
        return instance;
    }

    public FabricaConexao() {
        this.connectionPool = new ArrayList<Connection>();
        initialize();
    }


    private void initialize() {
        //Here we can initialize all the information that we need
        initializeConnectionPool();
    }

    private void initializeConnectionPool() {
        while (!checkIfConnectionPoolIsFull()) {
            System.out.println("Connection Pool is NOT full. Proceeding with adding new connections");
            //Adding new connection instance until the pool is full
            connectionPool.add(createNewConnectionForPool());
        }
        System.out.println("Connection Pool is full.");
    }

    private synchronized boolean checkIfConnectionPoolIsFull() {
        final int MAX_POOL_SIZE = 10;

        //Check if the pool size
        if (connectionPool.size() < MAX_POOL_SIZE) {
            return false;
        }

        return true;
    }

    //Creating a connection
    private Connection createNewConnectionForPool() {
        Connection connection = null;

        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(url, user, pass);
            System.out.println("Connection: " + connection);
        } catch (SQLException sqle) {
            System.err.println("SQLException: " + sqle);
            return null;
        } catch (ClassNotFoundException cnfe) {
            System.err.println("ClassNotFoundException: " + cnfe);
            return null;
        }

        return connection;
    }

    public synchronized Connection getConnectionFromPool() throws FabricaConexaoPoolVazioException {
        Connection connection = null;

        //Check if there is a connection available. There are times when all the connections in the pool may be used up
        if (connectionPool.size() > 0) {
            connection = (Connection) connectionPool.get(0);
            connectionPool.remove(0);

        } else {
            throw new FabricaConexaoPoolVazioException("pool de Conexao vazia");
        }
        //Giving away the connection from the connection pool
        return connection;
    }

    public synchronized void returnConnectionToPool(Connection connection) {
        //Adding the connection from the client back to the connection pool
        connectionPool.add(connection);
    }

    public void closeAllConnections() throws FabricaConexaoPoolVazioException {

        try {
            for (int i = 0; i < connectionPool.size(); i++) {
                connectionPool.get(i).close();
                connectionPool.remove(i);
                System.out.println("fechando conexoes " + i);
            }
        } catch (SQLException ex) {
            throw new FabricaConexaoPoolVazioException(FabricaConexaoPoolVazioException.ERRO_FECHAR_CONEXAO_POOL);
        }
    }

}
